
-- $Id: ScrollFrame.lua 72 2009-04-06 11:38:08Z Fylgjas $

-- ========================================================================= --
-- Copyright © 2009 Thomas ROBERT (aka Fylgjas EU - Marécage de Zangar)      --                                            --
-- ========================================================================= --
-- This file is part of FyLooter.                                            --
--                                                                           --
-- FyLooter is free software: you can redistribute it and/or modify it under --
-- the terms of the GNU General Public License as published by the Free      --
-- Software Foundation, either version 3 of the License, or (at your option) --
-- any later version.                                                        --
--                                                                           --
-- FyLooter is distributed in the hope that it will be useful, but WITHOUT   --
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     --
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for  --
-- more details.                                                             --
--                                                                           --
-- You should have received a copy of the GNU General Public License along   --
-- with FyLooter. If not, see <http://www.gnu.org/licenses/>.                --
-- ========================================================================= --

local revision = tonumber(string.sub("$Rev: 72 $", 7, -3));

if (FyLooter.revision < revision) then
  FyLooter.revision = revision;
end

-- ========================================================================= --

-- 
-- _scroll()
--
local function _scroll(self, delta)
  local slider = self:GetParent().ScrollBar.Slider;
  slider:SetValue(slider:GetValue() - delta);
end

-- 
-- _scroll_up()
--
local function _scroll_up(self, delta)
  local slider = self:GetParent().Slider;
  slider:SetValue(slider:GetValue() - 1);
end

-- 
-- _scroll_down()
--
local function _scroll_down(self, delta)
  local slider = self:GetParent().Slider;
  slider:SetValue(slider:GetValue() + 1);
end

-- 
-- _resize_viewport()
--
local function _resize_viewport(self)
  local offset = 0;
  if (self:IsVisible()) then
    offset = -self:GetWidth();
  end

  self:GetParent().Viewport:SetPoint("BOTTOMRIGHT", offset, 0);
end

-- 
-- _update()
--
local function _update(self)
  self:GetParent():GetParent():Update();
end

-- ========================================================================= --

-- 
-- FyLooter:CreateScrollFrame()
--
function FyLooter:CreateScrollFrame(parent, size)
  -- ScrollFrame
  local ScrollFrame = CreateFrame("Frame", nil, parent);
  ScrollFrame:Hide();
  ScrollFrame.size = size or 10;
  ScrollFrame:SetHeight(16 * ScrollFrame.size + 8);
  ScrollFrame:SetScript("OnShow", function(self) self:Update() end);

  -- ScrollFrame.Viewport
  ScrollFrame.Viewport = CreateFrame("Frame", nil, ScrollFrame);
  ScrollFrame.Viewport:SetPoint("TOPLEFT");
  ScrollFrame.Viewport:SetPoint("BOTTOMRIGHT");
  ScrollFrame.Viewport:SetBackdrop(FyLooter.db.settings.backdrop);
  ScrollFrame.Viewport:EnableMouseWheel(true);
  ScrollFrame.Viewport:SetScript("OnMouseWheel", _scroll);
  
  -- ScrollFrame.ScrollBar
  ScrollFrame.ScrollBar = CreateFrame("Frame", nil, ScrollFrame);
  ScrollFrame.ScrollBar:Hide();
  ScrollFrame.ScrollBar:SetWidth(24);
  ScrollFrame.ScrollBar:SetPoint("TOPRIGHT");
  ScrollFrame.ScrollBar:SetPoint("BOTTOMRIGHT");
  ScrollFrame.ScrollBar:SetBackdrop(FyLooter.db.settings.backdrop);
  ScrollFrame.ScrollBar:SetScript("OnShow", _resize_viewport);
  ScrollFrame.ScrollBar:SetScript("OnHide", _resize_viewport);

  -- ScrollFrame.ScrollBar.UpButton
  ScrollFrame.ScrollBar.UpButton = CreateFrame("Button", nil, ScrollFrame.ScrollBar, "UIPanelScrollUpButtonTemplate");
  ScrollFrame.ScrollBar.UpButton:SetWidth(16);
  ScrollFrame.ScrollBar.UpButton:SetHeight(16);
  ScrollFrame.ScrollBar.UpButton:SetPoint("TOP", 0, -4);
  ScrollFrame.ScrollBar.UpButton:SetScript("OnClick", _scroll_up);
  
  -- ScrollFrame.ScrollBar.DownButton
  ScrollFrame.ScrollBar.DownButton = CreateFrame("Button", nil, ScrollFrame.ScrollBar, "UIPanelScrollDownButtonTemplate");
  ScrollFrame.ScrollBar.DownButton:SetWidth(16);
  ScrollFrame.ScrollBar.DownButton:SetHeight(16);
  ScrollFrame.ScrollBar.DownButton:SetPoint("BOTTOM", 0, 4);
  ScrollFrame.ScrollBar.DownButton:SetScript("OnClick", _scroll_down);
  
  -- ScrollFrame.ScrollBar.Slider
  ScrollFrame.ScrollBar.Slider = CreateFrame("Slider", nil, ScrollFrame.ScrollBar);
  ScrollFrame.ScrollBar.Slider:SetWidth(16);
  ScrollFrame.ScrollBar.Slider:SetPoint("TOP", ScrollFrame.ScrollBar.UpButton, "BOTTOM");
  ScrollFrame.ScrollBar.Slider:SetPoint("BOTTOM", ScrollFrame.ScrollBar.DownButton, "TOP");
  ScrollFrame.ScrollBar.Slider:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob");
  ScrollFrame.ScrollBar.Slider:SetValueStep(1);
  ScrollFrame.ScrollBar.Slider:SetMinMaxValues(0, 0);
  ScrollFrame.ScrollBar.Slider:SetValue(0);
  ScrollFrame.ScrollBar.Slider:SetScript("OnValueChanged", _update);

  local t = ScrollFrame.ScrollBar.Slider:GetThumbTexture();
  t:SetWidth(16);
  t:SetHeight(16);
  t:SetTexCoord(0.25, 0.75, 0.25, 0.75);

  -- 
  -- ScrollFrame:SetModel()
  --
  function ScrollFrame:SetModel(model)
    self.model = model;
    model:Update();
  end

  -- 
  -- ScrollFrame:SetDelegates()
  --
  function ScrollFrame:SetDelegate(delegates)
    self.delegates = delegates;
    self:Update();
  end

  --
  -- ScrollFrame:GetOffset()
  --
  function ScrollFrame:GetOffset()
    return self.ScrollBar.Slider:GetValue();
  end

  -- 
  -- ScrollFrame:SetOffset()
  --
  function ScrollFrame:SetOffset(offset)
    self.ScrollBar.Slider:SetValue(offset);
  end

  -- 
  -- ScrollFrame:Update()
  --
  function ScrollFrame:Update()
    if (not self:IsVisible()) then return end

    local numItems = self.model:GetNumItems();
    local max = numItems - self.size;

    if (max > 0) then
      self.ScrollBar.Slider:SetMinMaxValues(0, max);
      self.ScrollBar:Show();
    else
      self.ScrollBar.Slider:SetMinMaxValues(0, 0);
      self.ScrollBar:Hide();
    end

    local offset = self.ScrollBar.Slider:GetValue();

    for i = 1, self.size do
      local idx = offset + i;
      local delegate = FyLooter.Delegates[i];

      if (idx > numItems) then
        delegate:Hide();
      else
        delegate:GetNormalTexture():SetVertexColor(0.5, 0.5, 0.5, 0.5);

        local player, character, level, class, color, hasChild, isExpanded, status = self.model:GetData(idx);
      
        if (not character) then
          if (hasChild) then
            if (isExpanded) then
              delegate.ExpandButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
              delegate.ExpandButton:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down");
            else
              delegate.ExpandButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
              delegate.ExpandButton:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down");
            end

            delegate.ExpandButton:Show();
          else
            delegate.ExpandButton:Hide();
          end

          delegate.NameLabel:SetFontObject(GameFontNormalSmall);
          delegate.NameLabel:SetText(player);

          delegate.LevelLabel:Hide();
          delegate.ClassLabel:Hide();
        else
          delegate.ExpandButton:Hide();

          delegate.NameLabel:SetFontObject(GameFontHighlightSmall);
          delegate.NameLabel:SetText(character);

          if (level > 0) then
            delegate.LevelLabel:SetText(level);
            delegate.LevelLabel:Show();
          else
            delegate.LevelLabel:Hide();
          end

          if (class) then
            delegate.ClassLabel:SetText(class);
            delegate.ClassLabel:SetTextColor(color.r, color.g, color.b);
            delegate.ClassLabel:Show();
          else
            delegate.ClassLabel:Hide();
          end

          if (status == FyLooter.Status.NEED) then
            delegate:GetNormalTexture():SetVertexColor(0.5, 1, 0.5, 0.5);
          elseif (status == FyLooter.Status.GREED) then
            delegate:GetNormalTexture():SetVertexColor(0.5, 0.5, 1, 0.5);
          elseif (status == FyLooter.Status.PASS) then
            delegate:GetNormalTexture():SetVertexColor(1, 0.5, 0.5, 0.5);
          end
        end

        if (idx == self.model:GetSelection()) then
          delegate:LockHighlight();
        else
          delegate:UnlockHighlight();
        end

        delegate:Show();
      end
    end
  end

  return ScrollFrame;
end

-- ========================================================================= --

